[% setvar title docs/pdds/pdd15_objects.pod - Object and Class semantics for Parrot %]
<div id="archive-notice">
    <h3>This file is part of the Perl 6 Archive</h3>
    <p>To see what is currently happening visit <a href="http://www.perl6.org/">http://www.perl6.org/</a></p>
</div>
<div class='pod'>
<a name='NAME'></a><h1>NAME</h1>
<p>docs/pdds/pdd15_objects.pod - Object and Class semantics for Parrot</p>
<a name='ABSTRACT'></a><h1>ABSTRACT</h1>
<p>This PDD describes the semantics of Parrot's object and class
systems. The PDD is divided into two parts, the semantics expressed
to user programs through PMCs, and the default back-end class scheme.</p>
<p>Note that the class system is <i>not</i> the single mandated class
scheme, merely the one designed to express the semantics needed for
perl 6, ruby, and python. Alternate class systems are certainly
possible, and direct compatibility with the system as described here
isn't strictly necessary.</p>
<a name='DESCRIPTION'></a><h1>DESCRIPTION</h1>
<p>This is a reasonably straightforward object system. It assumes that
objects have:</p>
<ul>
<li><a name='An array of attributes. Note that attribute values are always PMCs.'></a>An array of attributes. Note that attribute values are <i>always</i> PMCs.</li>
<li><a name='A parent class'></a>A parent class</li>
<li><a name='A custom (though possibly class-wide) vtable'></a>A custom (though possibly class-wide) vtable</li>
</ul>
<p>and that you can:</p>
<ul>
<li><a name='Call a method on an object'></a>Call a method on an object</li>
<li><a name='Get a method PMC for a method for an object (for deferred method calls)'></a>Get a method PMC for a method for an object (for deferred method calls)</li>
<li><a name='Fetch the class for an object'></a>Fetch the class for an object</li>
<li><a name='Subclass an existing object (note that objects may not necessarily be able to have their classes changed arbitrarily, but making a subclass and moving the object to it is allowable)'></a>Subclass an existing object (note that objects may not necessarily be
able to have their classes changed arbitrarily, but making a subclass
and moving the object to it is allowable)</li>
<li><a name='Get an attribute by name or offset'></a>Get an attribute by name or offset</li>
<li><a name='Set an attribute by name or offset'></a>Set an attribute by name or offset</li>
</ul>
<p>Additionally we assume that <i>all</i> objects can have properties on
them, as all PMCs can have properties. The property get/set method may
be overridden on a per-class basis as any other vtable method may be.</p>
<p>For classes, we assume that:</p>
<ul>
<li><a name='Classes have an associated namespace. (Which may be anonymous)'></a>Classes have an associated namespace. (Which may be anonymous)</li>
<li><a name='Classes have one or more immediate parent classes'></a>Classes have one or more immediate parent classes</li>
<li><a name='Classes have a catalog of attribute names and offsets for all attributes.'></a>Classes have a catalog of attribute names and offsets for all
attributes.</li>
<li><a name='Classes have a list of interfaces they implement'></a>Classes have a list of interfaces they implement</li>
</ul>
<p>And we further assume that classes can:</p>
<ul>
<li><a name='Instantiate an object of their class'></a>Instantiate an object of their class</li>
<li><a name='Add parent classes'></a>Add parent classes</li>
<li><a name='Remove parent classes'></a>Remove parent classes</li>
<li><a name='Add attributes'></a>Add attributes</li>
<li><a name='Remove attributes'></a>Remove attributes</li>
<li><a name='Add interfaces'></a>Add interfaces</li>
<li><a name='Remove interfaces'></a>Remove interfaces</li>
</ul>
<p>This list is likely not definitive, but it's enough to start
with. It also doesn't address the semantics of method calls, which
need to be dealt with, possibly separately. With that in mind, the
object system supports these features with a combination of PMC
classes (not to be confused with object classes) and opcodes.</p>
<a name='IMPLEMENTATION'></a><h1>IMPLEMENTATION</h1>
<p>There are four pieces to the object implementation. There are the PMCs
for the classes and objects, the opcodes the engine uses to do objecty
things, the specific vtable methods used to perform those objecty
things, and the supporting code provided by the interpreter engine to
do the heavy lifting.</p>
<p>Please note that Parrot, in general, does <i>not</i> restrict operations
on objects and classes. If a language has restrictions on what can be
done with them, the language is responsible for making sure that
disallowed things do not happen. For example, Parrot permits multiple
inheritance, and will not stop code that adds a new parent to an
existing class. If a language doesn't allow for multiple inheritance
it must not emit code which would add multiple parents to a
class. (Parrot may, at some point, allow imposition of runtime
restrictions on a class, but currently it doesn't)</p>
<a name='PMCs'></a><h2>PMCs</h2>
<p>There are two PMC classes, <code>ParrotClass</code> and
<code>ParrotObject</code>. ParrotObject PMCs are the actual objects, and
hold all the per-object instance data. ParrotClass PMCs hold all the
class-specific information. Instantiating a new OO class creates a new
ParrotClass PMC, and enters the new OO class into Parrot's PMC class
table, at which point it is indistinguishable from any other PMC
class. (This doesn't mean that non-ParrotClass things can be
subclassed or treated as an OO class. Neither is that forbidden. Just
unimplemented)</p>
<p>It's important to note that <i>all</i> 'standard' classes are
ParrotClass PMC instances, and <i>all</i> 'standard' objects are
ParrotObject PMCs. We do <i>not</i> create a brand new PMC class for each
OO class, and they all share the ParrotClass or ParrotObject vtable,
respectively. This distinction is mostly an artifact of the
implementation, and may change in the future.</p>
<p>While the internals of the class and object PMCs should be considered
black boxes, here's some documentation as to what they are for
implementation purposes.</p>
<p>The ParrotClass PMC holds a 6 element array, which is:</p>
<ul>
<li><a name='0'></a>0</li>
<p>An array PMC of the immediate parent classes</p>
<li><a name='1'></a>1</li>
<p>The class name PMC</p>
<li><a name='2'></a>2</li>
<p>An array of all parent PMCs, in search order</p>
<li><a name='3'></a>3</li>
<p>The class attribute section hash. Keys are the class name in
language-defined format (so perl would be foo::bar, while java would
be some.damn.long.thing.with.dots), values are the integer offset from
the start of the attribute array where that class' attributes start.</p>
<li><a name='4'></a>4</li>
<p>The class attribute name hash. Keys are the fully qualified attribute
names and the values are the offset from the beginning of the
attribute array of the particular attribute.</p>
<li><a name='5'></a>5</li>
<p>The class attribute array. This is an array of unqualified attribute
names.</p>
</ul>
<p>Note that the attribute catalog holds <i>all</i> the attributes for an
object. This includes the attributes in the object's class as well as
<i>all</i> the attributes defined in all the parent classes. (Multiple
inheritance makes this necessary -- the offsets of a class' attributes
will change from child class to child class)</p>
<p>ParrotClass PMCs also have the &quot;I am a class&quot; flag set on them.</p>
<p>The ParrotObject PMC is an array of meta-information and
attributes. The elements of this array are:</p>
<ul>
<li><a name='0'></a>0</li>
<p>The class PMC</p>
<li><a name='1'></a>1</li>
<p>The class name PMC</p>
<li><a name='2+'></a>2+</li>
<p>The attributes for the object</p>
</ul>
<p>Note that ParrotObject PMCs also have the &quot;I am an object&quot; flag set on
them.</p>
<a name='Opcodes'></a><h2>Opcodes</h2>
<p>The following ops are provided to deal with objects. Please note that
method calls are governed by parrot's calling conventions, and as such
objects, method PMCs, return continuations, and parameters must be in
the right places, though some ops will put parameters where they need
to go.</p>
<ul>
<li><a name='classoffset Ix, Py, Sz'></a>classoffset Ix, Py, Sz</li>
<p>Returns the offset of the first attribute for class Sz in object Py.</p>
<li><a name='getattribute Px, Py, Iz'></a>getattribute Px, Py, Iz</li>
<p>Returns attribute Iz of object Py and puts it in Px. Note that the
attribute number is an absolute offset.</p>
<li><a name='getattribute Px, Py, Sz'></a>getattribute Px, Py, Sz</li>
<p>Get the attribute with the fully qualified name Sz from object Py and
put it in Px.</p>
<li><a name='setattribute Px, Iy, Pz'></a>setattribute Px, Iy, Pz</li>
<p>Set the attribute Iy of object Px to Pz. Note that this op stores the
<b>actual</b> PMC rather than a copy, and so if the PMC's value is subsequently
changed, the value of the attribute will also change.</p>
<li><a name='setattribute Px, Sy, Pz'></a>setattribute Px, Sy, Pz</li>
<p>Set the attribute of object Px with the fully qualified name Sy to Pz</p>
<li><a name='fetchmethod Px, Py, Sz'></a>fetchmethod Px, Py, Sz</li>
<p>Find the PMC for method Sz of object Py, and put it in Px. Note that how
the method PMC returned behaves if it goes out of scope or if the
class hierarchy changes or the method definitions change is entirely
up to the class that provides the PMC.</p>
<li><a name='callmethod'></a>callmethod</li>
<li><a name='callmethod Sz'></a>callmethod Sz</li>
<p>Call a method. If the method name is provided, we find the PMC for the named
method and put it in the sub/method slot. If no name is provided we
assume that all the calling conventions have already been set up and
the method PMC is already in the proper place.</p>
<li><a name='callmethodcc'></a>callmethodcc</li>
<li><a name='callmethodcc Sx'></a>callmethodcc Sx</li>
<p>Make a method call, automatically generating a return continuation. If
a method name is passed in we look up the method PMC for the object
and put it in the method slot. If a method name isn't provided then we
assume that things are already properly set up.</p>
<li><a name='tailcallmethod (Unimplemented)'></a>tailcallmethod (Unimplemented)</li>
<li><a name='tailcallmethod Sx (Unimplemented)'></a>tailcallmethod Sx (Unimplemented)</li>
<p>Make a tailcall to method Sx. If no method name is given, we assume
everything is already set up properly.</p>
<li><a name='newclass Px, Sy'></a>newclass Px, Sy</li>
<p>Create a new base class named Sy, and put the PMC for it in Px</p>
<li><a name='subclass Px, Py, Sz'></a>subclass Px, Py, Sz</li>
<p>Create a new class, named Sz, which has Py as its immediate parent.</p>
<li><a name='addparent Px, Py'></a>addparent Px, Py</li>
<p>Add class Py to the end of the list of immediate parents of class
Px. Adds any attributes of Py (and its parent classes) that aren't
already in Px.</p>
<li><a name='removeparent Px, Py (Unimplemented)'></a>removeparent Px, Py (Unimplemented)</li>
<p>Remove class Py from the parent list of Px. All parent classes of Py
which aren't parent classes of what remains of Px's parent list are
removed, as are their attributes.</p>
<li><a name='addattribute Px, Sy'></a>addattribute Px, Sy</li>
<p>Add attribute Sy to class Px. This will add the attribute slot to all
objects of class Px and children of class Px, with a default value of
<code>Null</code>.</p>
<li><a name='removeattribute Px, Sy (Unimplemented)'></a>removeattribute Px, Sy (Unimplemented)</li>
<p>Remove the attribute Sy from class Px, all objects of class Px, and
all objects of a child of class Px.</p>
<li><a name='instantiate Px, Py, Sz (Unimplemented)'></a>instantiate Px, Py, Sz (Unimplemented)</li>
<p>Instantiate a brand new class, based on the metadata in Py, named Sz.</p>
</ul>
<a name='Vtables'></a><h2>Vtables</h2>
<p>To make this work all PMCs must have the following vtable
entries. They may, for non-objects, throw an exception.</p>
<p>The catalog metadata for objects is considered to be attributes on the
class, so to get the offset for a class for an object, you fetch the
object's class then look up the offset attribute from it. (The class
attributes are detailed later) This is safe in general, since the only
code reasonably querying a class' attribute list is the class code
itself, and if a class doesn't know whether it's a ParrotClass-style
class or not you've got bigger problems.</p>
<ul>
<li><a name='find_method(string *)'></a>find_method(string *)</li>
<p>Returns the PMC for the named method. If no method of this name
exists, nor can be constructed, returns a Null PMC.</p>
<p>Note that for languages which support default fallback methods, such
as Perl 5's AUTOLOAD, this would be the place to return it if a normal
lookup fails.</p>
<li><a name='isa(class *)'></a>isa(class *)</li>
<p>Returns true or false if the class passed in as a parameter is in the
inheritance hierarchy of the object.</p>
<li><a name='can(string *)'></a>can(string *)</li>
<p>Returns true or false if the object can perform the requested
method. (Including with an AUTOLOAD)</p>
<li><a name='does(class *)'></a>does(class *)</li>
<p>Returns true or false to note whether the object in question
implements the interface passed in.</p>
<li><a name='get_attr(INTVAL)'></a>get_attr(INTVAL)</li>
<p>Returns the attribute at the passed-in offset for the object.</p>
<li><a name='get_attr(STRING*)'></a>get_attr(STRING*)</li>
<p>Returns the attribute with the fully qualified name for the object.</p>
<li><a name='set_attr(INTVAL, PMC *)'></a>set_attr(INTVAL, PMC *)</li>
<p>Sets the attribute for the passed-in offset to the passed-in PMC value</p>
<li><a name='set_attr(STRING*, PMC *)'></a>set_attr(STRING*, PMC *)</li>
<p>Set the attribute with the fully qualified name for the object.</p>
<li><a name='get_class'></a>get_class</li>
<p>Returns the class PMC for the object.</p>
</ul>
<p>Currently Parrot only supports mutating a class' metainformation for
ParrotClass classes. This is a restriction which will be lifted at
some point soon.</p>
<a name='What The Bytecode Sees'></a><h1>What The Bytecode Sees</h1>
<p>The bytecode is isolated from most of the internal details of the
implementation. This allows both for flexibility in the implementation
and forward compatibility, generally good things. It also allows for
multiple concurrent interoperable object systems. The major thrust is
for transparent use of objects, though most class activity (including
creation of subclasses and modifications of existing classes) should
be transparent as well.</p>
<a name='EXAMPLES'></a><h1>EXAMPLES</h1>
<p>The following examples all assume we're working with basic
ParrotObject objects and ParrotClass classes.</p>
<a name='Creating a new class'></a><h2>Creating a new class</h2>
<p>To create a new class <code>Foo</code> which has no parent classes:</p>
<pre>   newclass $P0, &quot;Foo&quot;</pre>
<a name='Creating a new class with multiple parents'></a><h2>Creating a new class with multiple parents</h2>
<p>To create a class <code>Foo</code> with the parents <code>A</code> and <code>B</code>, the code
would be:</p>
<pre>   getclass $P0, &quot;A&quot;
   getclass $P1, &quot;B&quot;
   subclass $P2, $P0, &quot;Foo&quot;
   addparent $P2, $P1</pre>
<a name='Creating a new class with attributes'></a><h2>Creating a new class with attributes</h2>
<p>Adding the attributes <code>a</code> and <code>b</code> to the new class <code>Foo</code>:</p>
<pre>  newclass $P0, &quot;Foo&quot;
  addattribute $P0, &quot;a&quot;   # This is offset 0 + classoffset
  addattribute $P0, &quot;b&quot;   # This is offset 1 + classoffset</pre>
<a name='Instantiating an object'></a><h2>Instantiating an object</h2>
<p>Assuming we want an object of class <code>Foo</code>:</p>
<pre>  .local int FooType
  .local pmc MyObject
  find_type FooType, &quot;Foo&quot;
  new MyObject, FooType</pre>
<a name='Calling a method on an object'></a><h2>Calling a method on an object</h2>
<p>Calling the method <code>Xyzzy</code> on an object, assuming the PDD03 calling
conventions are respected:</p>
<pre>  callmethod &quot;Xyzzy&quot;

  set S0, &quot;Xyzzy&quot;
  callmethod</pre>
<p>Or, if a return continuation needs constructing:</p>
<pre>  callmethodcc &quot;Xyzzy&quot;

  set S0, &quot;Xyzzy&quot;
  callmethodcc</pre>
<a name='Accessing attributes from within a class'></a><h2>Accessing attributes from within a class</h2>
<p>Assuming we've an object that has class <code>Foo</code> in it somewhere and
want to get the second attribute <code>b</code> out of it:</p>
<pre>  .local int BaseOffset
  .local int BOffset
  classoffset BaseOffset, $P0, &quot;Foo&quot;
  BOffset = BaseOffset + 1
  getattribute $P1, $P0, BOffset</pre>
<p>Or with named access, if it isn't time critical:</p>
<pre>  getattribute $P1, $P0, &quot;Foo\x0b&quot;</pre>
<a name='Explanations'></a><h1>Explanations</h1>
<p>To get a new class, you can do a <code>newclass</code>, which creates a new
class with no parents besides parrot's default super-ish parent
class. (Which doesn't appear in the class list anywhere, though
arguably it ought to)</p>
<p>To get a new child class, you have two potential options:</p>
<ul>
<li><a name='Subclass the parent'></a>Subclass the parent</li>
<li><a name='Create a new standalone class and add a parent'></a>Create a new standalone class and add a parent</li>
</ul>
<p>Both ways work. It is, however, more efficient to use the first
method, and just subclass the immediate parent class of your new
class.</p>
<p>When adding in extra parents in a multiple-inheritance scenario,
subclass the first class in the immediate parent list then use the
<code>addparent</code> op to add in the rest of the immediate parents.</p>
<p>Do be aware that, right now, you should <i>not</i> add attributes or
parents to a class that's been subclassed or has had objects
instantiated. This will leave the internal structures of the classes
and objects in an inconsistent state and things won't work at all the
way you want them to. At the moment parrot won't warn if you do this,
but it will soon. The restriction on parent list changes and attribute
addition will be lifted in future releases, though doing so will be an
expensive operation.</p>
<a name='VTABLE OVERLOADING'></a><h1>VTABLE OVERLOADING</h1>
<p>Classes may override the vtable methods, allowing objects of a class
to behave like a primitive PMC. Each vtable slot has a
corresponding named method that parrot looks for in your class
hierarchy when an object is used in a primitive context.</p>
<p>To use these properly at a low-level requires a good working knowledge
of the way Parrot works--generally for higher-level languages the
language compiler or runtime will provide easier-to-use
wrappers. These methods are all prototyped, and take a single fixed
argument list, and return at most a single value.</p>
<p>While vtable methods <i>may</i> take a continuation, those continuations
may <i>not</i> escape the vtable method's execution. This is due to the
way that vtable methods are called by the interpreter--once a vtable
method is exited any continuation taken within it is no longer valid
and may not be used.</p>
<p>Note that any class method that wishes to use parrot's multi-method
dispatch system may do so. This is, in fact, encouraged, though it is
not required. In the absence of explicit multimethod dispatch, a
left-side wins scheme is used.</p>
<p>The following list details the raw method names:</p>
<ul>
<li><a name='__init'></a>__init</li>
<p>Called when the object is first created.</p>
<li><a name='__init_pmc'></a>__init_pmc</li>
<li><a name='__init_pmc_props'></a>__init_pmc_props</li>
<li><a name='__morph'></a>__morph</li>
<li><a name='__mark'></a>__mark</li>
<p>Called when the DOD is tracing live PMCs. If this method is called
then the code must mark all strings and PMCs that it contains as
live, otherwise they may be collected.</p>
<p>This method is only called if the PMC is flagged as having a special
mark routine, and is not necessary for normal objects.</p>
<li><a name='__destroy'></a>__destroy</li>
<p>Called when the object is destroyed. This method is only called if
the PMC is marked as having an active finalizer.</p>
<li><a name='__getprop'></a>__getprop</li>
<li><a name='__setprop'></a>__setprop</li>
<li><a name='__delprop'></a>__delprop</li>
<li><a name='__getprops'></a>__getprops</li>
<li><a name='__type'></a>__type</li>
<li><a name='__type_keyed'></a>__type_keyed</li>
<li><a name='__type_keyed_int'></a>__type_keyed_int</li>
<li><a name='__type_keyed_str'></a>__type_keyed_str</li>
<li><a name='__subtype'></a>__subtype</li>
<li><a name='__name'></a>__name</li>
<li><a name='__clone'></a>__clone</li>
<li><a name='__find_method'></a>__find_method</li>
<li><a name='__get_integer'></a>__get_integer</li>
<p>Return the integer value of the object</p>
<li><a name='__get_integer_keyed'></a>__get_integer_keyed</li>
<li><a name='__get_integer_keyed_int'></a>__get_integer_keyed_int</li>
<li><a name='__get_integer_keyed_str'></a>__get_integer_keyed_str</li>
<li><a name='__get_number'></a>__get_number</li>
<p>Return the floating-point value of the object</p>
<li><a name='__get_number_keyed'></a>__get_number_keyed</li>
<li><a name='__get_number_keyed_int'></a>__get_number_keyed_int</li>
<li><a name='__get_number_keyed_str'></a>__get_number_keyed_str</li>
<li><a name='__get_bignum'></a>__get_bignum</li>
<p>Return the extended precision numeric value of the PMC</p>
<li><a name='__get_bignum_keyed'></a>__get_bignum_keyed</li>
<li><a name='__get_bignum_keyed_int'></a>__get_bignum_keyed_int</li>
<li><a name='__get_bignum_keyed_str'></a>__get_bignum_keyed_str</li>
<li><a name='__get_string'></a>__get_string</li>
<p>Return the string value of the PMC</p>
<li><a name='__get_string_keyed'></a>__get_string_keyed</li>
<li><a name='__get_string_keyed_int'></a>__get_string_keyed_int</li>
<li><a name='__get_string_keyed_str'></a>__get_string_keyed_str</li>
<li><a name='__get_bool'></a>__get_bool</li>
<p>Return the true/false value of the PMC</p>
<li><a name='__get_bool_keyed'></a>__get_bool_keyed</li>
<li><a name='__get_bool_keyed_int'></a>__get_bool_keyed_int</li>
<li><a name='__get_bool_keyed_str'></a>__get_bool_keyed_str</li>
<li><a name='__get_pmc'></a>__get_pmc</li>
<p>Return the PMC for this PMC.</p>
<li><a name='__get_pmc_keyed'></a>__get_pmc_keyed</li>
<li><a name='__get_pmc_keyed_int'></a>__get_pmc_keyed_int</li>
<li><a name='__get_pmc_keyed_str'></a>__get_pmc_keyed_str</li>
<li><a name='__get_pointer'></a>__get_pointer</li>
<li><a name='__get_pointer_keyed'></a>__get_pointer_keyed</li>
<li><a name='__get_pointer_keyed_int'></a>__get_pointer_keyed_int</li>
<li><a name='__get_pointer_keyed_str'></a>__get_pointer_keyed_str</li>
<li><a name='__set_integer_native'></a>__set_integer_native</li>
<p>Set the integer value of this PMC</p>
<li><a name='__set_integer_same'></a>__set_integer_same</li>
<li><a name='__set_integer_keyed'></a>__set_integer_keyed</li>
<li><a name='__set_integer_keyed_int'></a>__set_integer_keyed_int</li>
<li><a name='__set_integer_keyed_str'></a>__set_integer_keyed_str</li>
<li><a name='__set_number_native'></a>__set_number_native</li>
<p>Set the floating-point value of this PMC</p>
<li><a name='__set_number_same'></a>__set_number_same</li>
<li><a name='__set_number_keyed'></a>__set_number_keyed</li>
<li><a name='__set_number_keyed_int'></a>__set_number_keyed_int</li>
<li><a name='__set_number_keyed_str'></a>__set_number_keyed_str</li>
<li><a name='__set_bignum_native'></a>__set_bignum_native</li>
<p>Set the extended-precision value of this PMC</p>
<li><a name='__set_bignum_same'></a>__set_bignum_same</li>
<li><a name='__set_bignum_keyed'></a>__set_bignum_keyed</li>
<li><a name='__set_bignum_keyed_int'></a>__set_bignum_keyed_int</li>
<li><a name='__set_bignum_keyed_str'></a>__set_bignum_keyed_str</li>
<li><a name='__set_string_native'></a>__set_string_native</li>
<p>Set the string value of this PMC</p>
<li><a name='__set_string_same'></a>__set_string_same</li>
<li><a name='__set_string_keyed'></a>__set_string_keyed</li>
<li><a name='__set_string_keyed_int'></a>__set_string_keyed_int</li>
<li><a name='__set_string_keyed_str'></a>__set_string_keyed_str</li>
<li><a name='__set_bool'></a>__set_bool</li>
<p>Set the true/false value of this PMC</p>
<li><a name='__set_bool_keyed'></a>__set_bool_keyed</li>
<li><a name='__set_bool_keyed_int'></a>__set_bool_keyed_int</li>
<li><a name='__set_bool_keyed_str'></a>__set_bool_keyed_str</li>
<li><a name='__set_pmc'></a>__set_pmc</li>
<p>Set the PMC to the PMC passed in</p>
<li><a name='__set_pmc_keyed'></a>__set_pmc_keyed</li>
<li><a name='__set_pmc_keyed_int'></a>__set_pmc_keyed_int</li>
<li><a name='__set_pmc_keyed_str'></a>__set_pmc_keyed_str</li>
<li><a name='__set_pointer'></a>__set_pointer</li>
<li><a name='__set_pointer_keyed'></a>__set_pointer_keyed</li>
<li><a name='__set_pointer_keyed_int'></a>__set_pointer_keyed_int</li>
<li><a name='__set_pointer_keyed_str'></a>__set_pointer_keyed_str</li>
<li><a name='__elements'></a>__elements</li>
<p>Return the number of elements in the PMC, if the PMC is treated as an
aggregate.</p>
<li><a name='__pop_integer'></a>__pop_integer</li>
<li><a name='__pop_float'></a>__pop_float</li>
<li><a name='__pop_bignum'></a>__pop_bignum</li>
<li><a name='__pop_string'></a>__pop_string</li>
<li><a name='__pop_pmc'></a>__pop_pmc</li>
<li><a name='__push_integer'></a>__push_integer</li>
<li><a name='__push_float'></a>__push_float</li>
<li><a name='__push_bignum'></a>__push_bignum</li>
<li><a name='__push_string'></a>__push_string</li>
<li><a name='__push_pmc'></a>__push_pmc</li>
<li><a name='__shift_integer'></a>__shift_integer</li>
<li><a name='__shift_float'></a>__shift_float</li>
<li><a name='__shift_bignum'></a>__shift_bignum</li>
<li><a name='__shift_string'></a>__shift_string</li>
<li><a name='__shift_pmc'></a>__shift_pmc</li>
<li><a name='__unshift_integer'></a>__unshift_integer</li>
<li><a name='__unshift_float'></a>__unshift_float</li>
<li><a name='__unshift_bignum'></a>__unshift_bignum</li>
<li><a name='__unshift_string'></a>__unshift_string</li>
<li><a name='__unshift_pmc'></a>__unshift_pmc</li>
<li><a name='__splice'></a>__splice</li>
<li><a name='__add'></a>__add</li>
<li><a name='__add_int'></a>__add_int</li>
<li><a name='__add_bignum'></a>__add_bignum</li>
<li><a name='__add_float'></a>__add_float</li>
<li><a name='__subtract'></a>__subtract</li>
<li><a name='__subtract_int'></a>__subtract_int</li>
<li><a name='__subtract_bignum'></a>__subtract_bignum</li>
<li><a name='__subtract_float'></a>__subtract_float</li>
<li><a name='__multiply'></a>__multiply</li>
<li><a name='__multiply_int'></a>__multiply_int</li>
<li><a name='__multiply_bignum'></a>__multiply_bignum</li>
<li><a name='__multiply_float'></a>__multiply_float</li>
<li><a name='__divide'></a>__divide</li>
<li><a name='__divide_int'></a>__divide_int</li>
<li><a name='__divide_bignum'></a>__divide_bignum</li>
<li><a name='__divide_float'></a>__divide_float</li>
<li><a name='__modulus'></a>__modulus</li>
<li><a name='__modulus_int'></a>__modulus_int</li>
<li><a name='__modulus_bignum'></a>__modulus_bignum</li>
<li><a name='__modulus_float'></a>__modulus_float</li>
<li><a name='__cmodulus'></a>__cmodulus</li>
<li><a name='__cmodulus_int'></a>__cmodulus_int</li>
<li><a name='__cmodulus_bignum'></a>__cmodulus_bignum</li>
<li><a name='__cmodulus_float'></a>__cmodulus_float</li>
<li><a name='__neg'></a>__neg</li>
<li><a name='__bitwise_or'></a>__bitwise_or</li>
<li><a name='__bitwise_or_int'></a>__bitwise_or_int</li>
<li><a name='__bitwise_and'></a>__bitwise_and</li>
<li><a name='__bitwise_and_int'></a>__bitwise_and_int</li>
<li><a name='__bitwise_xor'></a>__bitwise_xor</li>
<li><a name='__bitwise_xor_int'></a>__bitwise_xor_int</li>
<li><a name='__bitwise_ors'></a>__bitwise_ors</li>
<li><a name='__bitwise_ors_str'></a>__bitwise_ors_str</li>
<li><a name='__bitwise_ands'></a>__bitwise_ands</li>
<li><a name='__bitwise_ands_str'></a>__bitwise_ands_str</li>
<li><a name='__bitwise_xors'></a>__bitwise_xors</li>
<li><a name='__bitwise_xors_str'></a>__bitwise_xors_str</li>
<li><a name='__bitwise_not'></a>__bitwise_not</li>
<li><a name='__bitwise_shl'></a>__bitwise_shl</li>
<li><a name='__bitwise_shl_int'></a>__bitwise_shl_int</li>
<li><a name='__bitwise_shr'></a>__bitwise_shr</li>
<li><a name='__bitwise_shr_int'></a>__bitwise_shr_int</li>
<li><a name='__concatenate'></a>__concatenate</li>
<li><a name='__concatenate_native'></a>__concatenate_native</li>
<li><a name='__is_equal'></a>__is_equal</li>
<li><a name='__is_same'></a>__is_same</li>
<li><a name='__cmp'></a>__cmp</li>
<li><a name='__cmp_num'></a>__cmp_num</li>
<li><a name='__cmp_string'></a>__cmp_string</li>
<li><a name='__logical_or'></a>__logical_or</li>
<li><a name='__logical_and'></a>__logical_and</li>
<li><a name='__logical_xor'></a>__logical_xor</li>
<li><a name='__logical_not'></a>__logical_not</li>
<li><a name='__repeat'></a>__repeat</li>
<li><a name='__repeat_int'></a>__repeat_int</li>
<li><a name='__increment'></a>__increment</li>
<li><a name='__decrement'></a>__decrement</li>
<li><a name='__exists_keyed'></a>__exists_keyed</li>
<li><a name='__exists_keyed_int'></a>__exists_keyed_int</li>
<li><a name='__exists_keyed_str'></a>__exists_keyed_str</li>
<li><a name='__defined'></a>__defined</li>
<li><a name='__defined_keyed'></a>__defined_keyed</li>
<li><a name='__defined_keyed_int'></a>__defined_keyed_int</li>
<li><a name='__defined_keyed_str'></a>__defined_keyed_str</li>
<li><a name='__delete_keyed'></a>__delete_keyed</li>
<li><a name='__delete_keyed_int'></a>__delete_keyed_int</li>
<li><a name='__delete_keyed_str'></a>__delete_keyed_str</li>
<li><a name='__nextkey_keyed'></a>__nextkey_keyed</li>
<li><a name='__nextkey_keyed_int'></a>__nextkey_keyed_int</li>
<li><a name='__nextkey_keyed_str'></a>__nextkey_keyed_str</li>
<li><a name='__substr'></a>__substr</li>
<li><a name='__substr_str'></a>__substr_str</li>
<li><a name='__invoke'></a>__invoke</li>
<li><a name='__can'></a>__can</li>
<li><a name='__does'></a>__does</li>
<li><a name='__isa'></a>__isa</li>
<li><a name='__freeze'></a>__freeze</li>
<li><a name='__thaw'></a>__thaw</li>
<li><a name='__thawfinish'></a>__thawfinish</li>
<li><a name='__visit'></a>__visit</li>
<li><a name='__share'></a>__share</li>
</ul>
<a name='TRANSLATION AND GLOSSARY'></a><h1>TRANSLATION AND GLOSSARY</h1>
<p>Since every object system on the planet shares a common set of terms
but uses them completely differently, this section defines</p>
<a name='Glossary'></a><h2>Glossary</h2>
<ul>
<li><a name='Property'></a>Property</li>
<p>A name and value pair attached to a PMC. Properties may be attached to
the PMC in its role as a container or the PMC in its role as a value.</p>
<p>Properties are global to the PMC. That is there can only be one
property named &quot;FOO&quot; attached to a PMC, and it is globally visible to
all inspectors of the PMCs properties. They are <i>not</i> restricted by
class.</p>
<p>Properties are generally assigned at runtime, and a particular
property may or may not exist on a PMC at any particular
time. Properties are not restricted to objects as such, and any PMC
may have a property attached to it.</p>
<li><a name='Attribute'></a>Attribute</li>
<p>An attribute is a slot in an object that contains a value, generally a
PMC. (Containing non-PMCs leads to interesting garbage collection
issues at the moment) Attributes are referenced either
by slot number or by class name/attribute name pairs. (At least
conceptually)</p>
<p>Attributes are set on a class-wide basis, and all the objects of a
class will have the same set of attributes. Generally attributes
aren't added or removed from classes at runtime, as this would require
resizing and moving the elements of the attribute arrays of existing
objects, and potentially recompiling code with fixed attribute offsets
embedded in it. Most OO languages don't allow attribute changes to
existing classes, though parrot's base attribute system does allow
this.</p>
<p>The fully qualified name of an attribute is the classname, a null, and
the attribute name. Parrot synthesizes the fully-qualified name where
it needs to.</p>
<li><a name='Method'></a>Method</li>
<p>In its strictest sense, a method is a chunk of code that you call with
an object in the object slot of the calling conventions.</p>
<p>More generally, a method is some piece of code that you invoke by name
through an object. You call the object's &quot;Invoke a method&quot; vtable
entry, passing in the method name (Assuming we don't just get it from
the sub name register, per calling conventions). The object is then
responsible for doing something with the method being
requested. Presumably it calls the method, though this isn't strictly
required.</p>
<li><a name='Delegate'></a>Delegate</li>
<p>An object that is transparently (to the user) embedded in another
object. Delegate objects are used in those cases where we can't
inherit from a class because the class is from a different object
universe.</p>
<p>As an example, assume you have a class A, which inherits from class
B. The classes are incompatible, so Parrot can't automatically meld B
into A, as it might if they were. When instantiating an object of
class A, Parrot will automatically instantiate an object of class B
and embed it in the object of class A. The object of class B is class
A's delegate--when a method call comes in that A can't handle, that
method call is delegated to B.</p>
<li><a name='Parent class'></a>Parent class</li>
<p>Also called the super-class. The parent class is, in an inheritance
situation, the class being derived from. If A derives from B, B is the
parent class of A.</p>
<li><a name='Child class'></a>Child class</li>
<p>Also called the sub-class. The child class is, in an inheritance
situation, the class doing the deriving. If A derives from B, A is the
child class.</p>
</ul>
<a name='Translation'></a><h2>Translation</h2>
<p>The following list a set of languages, then within each language what
the parrot term translates to.</p>
<ul>
<li><a name='Python'></a>Python</li>
<ul>
<li><a name='Attribute'></a>Attribute</li>
<p>A Python attribute maps to a parrot property</p>
</ul>
<li><a name='.NET'></a>.NET</li>
<ul>
<li><a name='Attribute'></a>Attribute</li>
<p>What .NET calls an attribute parrot calls a property</p>
<li><a name='Property'></a>Property</li>
<p>What .NET calls a property we call an attribute</p>
</ul>
<li><a name='Generic Terminology'></a>Generic Terminology</li>
<ul>
<li><a name='Instance Variable'></a>Instance Variable</li>
<p>Instance Variables map to what we call attributes</p>
</ul>
</ul>
<a name='ATTACHMENTS'></a><h1>ATTACHMENTS</h1>
<p>None.</p>
<a name='FOOTNOTES'></a><h1>FOOTNOTES</h1>
<p>None.</p>
<a name='REFERENCES'></a><h1>REFERENCES</h1>
<p>None.</p>
<a name='VERSION'></a><h1>VERSION</h1>
<a name='CURRENT'></a><h2>CURRENT</h2>
<pre>    Maintainer: Dan Sugalski
    Class: Internals
    PDD Number: 15
    Version: 1.2
    Status: Developing
    Last Modified: February 09, 2004
    PDD Format: 1
    Language: English</pre>
<a name='HISTORY'></a><h2>HISTORY</h2>
<ul>
<li><a name='Version 1.3'></a>Version 1.3</li>
<p>April 3, 2004</p>
<li><a name='Version 1.2'></a>Version 1.2</li>
<p>February 9, 2004</p>
<li><a name='Version 1.1'></a>Version 1.1</li>
<p>March 11, 2002</p>
<li><a name='version 1'></a>version 1</li>
<p>None. First version</p>
</ul>
<a name='CHANGES'></a><h1>CHANGES</h1>
<ul>
<li><a name='Version 1.3'></a>Version 1.3</li>
<p>Removed some unimplemented notes. Changed vtables to get_*, set_* so that they
match other vtable function syntax.</p>
<li><a name='Version 1.2'></a>Version 1.2</li>
<p>A complete overhaul from the original spec.</p>
<li><a name='Version 1.1'></a>Version 1.1</li>
<p>Removed attributes from the object interface and put them in the
class interface section, where they belong.</p>
<li><a name='Version 1.0'></a>Version 1.0</li>
<p>None. First version</p>
</ul>
</div>
